/**
 * @description 动态加载、执行initCommand
 * @author zjcat
 */
"use strict";
const path = require("path");
const Package = require("@spiritos-cli/package");
const log = require("@spiritos-cli/log");
const {exec:spawn} = require('@spiritos-cli/utils');
//配置表
const CACHE_DIR = "dependencies";
const SETTINGS = {
  init: "@imooc-cli/init",
};

async function exec() {
  let targetPath = process.env.CLI_TARGET_PATH;
  const homePath = process.env.CLI_HOME_PAHT;
  let pkg;
  let storeDir = "";
  log.verbose("targetPath", targetPath);
  log.verbose("homePath", homePath);

  const cmdObj = arguments[arguments.length - 1];
  const packageName = SETTINGS[cmdObj.name()];
  const packageVersion = "latest";
  //当targetPath不存在，就赋值给缓存路径
  if (!targetPath) {
    targetPath = path.resolve(homePath, CACHE_DIR);
    storeDir = path.resolve(targetPath, "node_modules");
    log.verbose("homePath", targetPath);
    log.verbose("storeDir", storeDir);
    pkg = new Package({
      targetPath,
      packageName,
      storeDir,
      packageVersion,
    });
    //是否需要更新
    if (await pkg.exists()) {
      //更新包
      await pkg.update();
    } else {
      //下载包
      await pkg.install();
    }
  } else {
    pkg = new Package({
      targetPath,
      packageName,
      packageVersion,
    });
    const rootFile = pkg.getRootFilePatn();
    if (rootFile) {
      //require(rootFile).bind(null, arguments); //将arguments数组装换成方法需要的对象
      try {
        //在当前进程中调用
        //require(rootFile).call(null, Array.from(arguments)); //Array.from es6新增属性 将类数组的对象转换成数组对象
        //在node子进程中调用
        const args = Array.from(arguments);
        const cmd = args[args.length - 1];
        const o = Object.create(null); //创建一个没有原型链的对象
        Object.keys(cmd).forEach((key) => {
          if (
            key === '_optionValues' ||
            cmd.hasOwnProperty(key) &&
            !key.startsWith("_") &&
            key !== "parent"
          ) {
            //是否有指定的键
            //判断是否已下划线开头的去掉
            o[key] = cmd[key];
          }
        });
        args[args.length - 1] = o;
        const code = `require('${rootFile}').call(null, ${JSON.stringify(args)})`;
        const child = spawn("node", ["-e", code], {
          cwd: process.cwd(),
          stdio: "inherit",
        });
        child.on("error", (e) => {
          log.error(e.message);
          process.exit(1);
        });
        //退出事件
        child.on("exit", (e) => {
          log.verbose("命令执行成功" + e);
          process.exit(e);
        });
      } catch (e) {
        log.error(e.message);
      }
    }
  }
}


module.exports = exec;
